package edu.kit.aifb.bowsim;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.logging.Logger;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.semanticweb.yars.nx.parser.Callback;
import org.semanticweb.yars.nx.parser.NxParser;
import org.semanticweb.yars.nx.parser.ParseException;
import org.semanticweb.yars.util.CallbackNxOutputStream;

import edu.kit.aifb.bowsim.index.TextIndexMatcher;
import edu.kit.aifb.bowsim.index.TextIndexWriter;

public class Main{
	private final static Logger _log = Logger.getLogger(Main.class.getSimpleName());

	public static void main(String[] args) throws FileNotFoundException, ParseException, IOException {
		Options options = new Options();

		Option indexO = new Option("i", "set index directory");
		indexO.setArgs(1);
		indexO.setRequired(true);
		indexO.setArgName("index directory");
		options.addOption(indexO);

		Option createO = new Option("c", "create index (from N-Triples file grouped by subject)");
		createO.setArgs(1);
		createO.setArgName("file");
		options.addOption(createO);
		
		Option matchO = new Option("m", "match (from N-Triples file grouped by subject)");
		matchO.setArgs(1);
		matchO.setArgName("file");
		options.addOption(matchO);
		
		OptionGroup createOrMatch = new OptionGroup();
		createOrMatch.setRequired(true);
		createOrMatch.addOption(matchO);
		createOrMatch.addOption(createO);
		options.addOptionGroup(createOrMatch);
		
		Option thresholdO = new Option("t", "threshold for match ]0...1] (default: 0.9)");
		thresholdO.setArgs(1);
		thresholdO.setArgName("threshold");
		options.addOption(thresholdO);

		Option outputO = new Option("o", "set output file name");
		outputO.setArgs(1);
		outputO.setArgName("output file name");
		options.addOption(outputO);

		Option helpO = new Option("h", "help", false, "print help");
		options.addOption(helpO);

		CommandLineParser parser = new BasicParser();
		HelpFormatter formatter = new HelpFormatter();
		CommandLine cmd = null;
		try {
			cmd = parser.parse(options, args, true);
		} catch (org.apache.commons.cli.ParseException e) {
			formatter.printHelp(80," ","ERROR: "+e.getMessage()+"\n", options,"\nError occured! Please see the error message above",true );
			System.exit(-1);
		} catch (NumberFormatException e) {
			formatter.printHelp(80," ","ERROR: "+e.getMessage()+"\n", options,"\nError occured! Please see the error message above",true );
			System.exit(-1);
		}

		PrintStream out = System.out;
		
		Callback c;

		if (cmd.hasOption("o")) {
			out = new PrintStream(new FileOutputStream(cmd.getOptionValue("o")));
		}

		c = new CallbackNxOutputStream(out);
		
		float threshold = 0.9f;
		
		if (cmd.hasOption("t")) {
			threshold = Float.valueOf(cmd.getOptionValue("t"));
		}

		long time = System.currentTimeMillis();

		if (cmd.hasOption("c")) {
			String infname = cmd.getOptionValue("c");
			
			NxParser nxp = new NxParser(new FileInputStream(infname));

			TextIndexWriter tiw = new TextIndexWriter(new File(cmd.getOptionValue("i")), "en", true);

			tiw.addAll(nxp);
			
			tiw.close();
		} else if (cmd.hasOption("m")) {
			String infname = cmd.getOptionValue("m");
			
			NxParser nxp = new NxParser(new FileInputStream(infname));
			
			File indexw = new File(cmd.getOptionValue("i"));
			
			TextIndexWriter tiw = new TextIndexWriter(indexw, "en", false);

			TextIndexMatcher tim = new TextIndexMatcher(tiw, "en", indexw);
			
			// do matching here...
			tim.matchAll(nxp, c, threshold);
			
			_log.info("closing index...");
			
			tiw.close();
		}

		long time1 = System.currentTimeMillis();

		System.err.println("time elapsed " + (time1-time) + " ms");
		
		out.close();
	}
}
